
/** 
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package org.tompai.common;

import com.alibaba.fastjson.JSONArray;

/**
* @desc: tompai-common
* @name: LonlatUtils.java
* @author: tompai
* @email：liinux@qq.com
* @createTime: 2021年2月4日 下午1:17:13
* @history:
* @version: v1.0
*/

public class LonlatUtils {
	 
	private static double PI = 3.14159265;
    private static double EARTH_RADIUS = 6378137;
    private static double RAD = Math.PI / 180.0;
 
   /**
    * @Description: 获取四至信息(最大最小经纬度)
    * @param lat 
    * @param lng 
    * @date 2019年4月25日 下午5:50:54
    */
    public static double[] getFourBounds(String lng, String lat, String[] pointArr) throws Exception {
       if (pointArr.length>1) {
         return getPolygonAround(pointArr);
      }
       return getCircleAround(Double.parseDouble(lng), Double.parseDouble(lat), Double.parseDouble(pointArr[0]));
       
    }
    /**
     * @Description:  获取多边形四至信息
     * @date 2019年4月26日 下午4:27:26
     */
   public static double[] getPolygonAround(String[] pointArr) {
      // 获取中心点
      double maxLat = 0.0;
      double maxLng = 0.0;
      double minLat = 1000.0;
      double minLng = 1000.0;
      for (String str : pointArr) {
         double lng = Double.parseDouble(str.split(",")[0]);
         double lat = Double.parseDouble(str.split(",")[1]);
         if (lat > maxLat) {
            maxLat = lat;
         }
         if (lng > maxLng) {
            maxLng = lng;
         }
         if (lat < minLat) {
            minLat = lat;
         }
         if (lng < minLng) {
            minLng = lng;
         }
      }
      return new double[] { minLat, minLng, maxLat, maxLng };
   }
    /// <summary>
    /// 根据提供的经度和纬度、以及半径，取得此半径内的最大最小经纬度
    /// </summary>
    /// <param name="lat">纬度</param>
    /// <param name="lon">经度</param>
    /// <param name="raidus">半径(米)</param>
    /// <returns></returns>
    public static double[] getCircleAround(double lon, double lat, double raidusMile)
    {
 
        Double latitude = lat;
        Double longitude = lon;
 
        Double degree = (24901 * 1609) / 360.0;
 
        Double dpmLat = 1 / degree;
        Double radiusLat = dpmLat * raidusMile;
        Double minLat = latitude - radiusLat;
        Double maxLat = latitude + radiusLat;
 
        Double mpdLng = degree * Math.cos(latitude * (PI / 180));
        Double dpmLng = 1 / mpdLng;
        Double radiusLng = dpmLng * raidusMile;
        Double minLng = longitude - radiusLng;
        Double maxLng = longitude + radiusLng;
        return new double[] { minLat, minLng, maxLat, maxLng };
    }
 
    /// <summary>
    /// 根据提供的两个经纬度计算距离(米) 误差10米 多了10米
    /// </summary>
    /// <param name="lng1">经度1</param>
    /// <param name="lat1">纬度1</param>
    /// <param name="lng2">经度2</param>
    /// <param name="lat2">纬度2</param>
    /// <returns></returns>
    public static double getDistance(double lng1, double lat1, double lng2, double lat2)
    {
        double radLat1 = lat1 * RAD;
        double radLat2 = lat2 * RAD;
        double a = radLat1 - radLat2;
        double b = (lng1 - lng2) * RAD;
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
         Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS;
        s = Math.round(s * 10000) / 10000;
        return s;
    }
    
 
    /**
     * 判断一个点是否在圆形区域内
     */
    public static boolean isInCircle(double lng1, double lat1, double lng2, double lat2, String radius) {
        double distance = getDistance(lat1, lng1, lat2, lng2);
        double r = Double.parseDouble(radius);
        if (distance > r) {
            return false;
        } else {
            return true;
        }
    }
    
    public static void main(String[] args) {
       System.out.println(JSONArray.toJSONString(getCircleAround(116.407863, 39.914087,480)));
      System.out.println(getDistance(116.407863, 39.914087, 116.413486,39.914336));
   }


}

